package org.ala.tree.lsm.sstable.block;

import java.nio.ByteBuffer;

import org.ala.tree.lsm.tools.BloomFilter;
import org.ala.tree.lsm.tools.KryoTools;

/**
 * 元数据块
 * <p>	布隆过滤器
 * <p>	[键值对总数（4字节） | 写文件时间戳（8字节） | DataBlock容量（4字节） | 布隆过滤器长度（4字节） | 元数据段]
 * 
 * @author ala
 * @date 2025年5月28日
 */
public class MetaBlock {
	public static final int HEAD_LEN = 20;
	
	
	/**
	 * 	键值对总数
	 */
	protected int count;
	/**
	 * 	写文件时间戳
	 */
	protected long timestamp = -1;
	/**
	 * 	DataBlock中数据容量（单位：kv个数）
	 */
	protected int dataBlockCapacity;
	/**
	 * 	布隆过滤器
	 */
	protected BloomFilter bf;
	
	
	public MetaBlock(int count, int dataBlockCapacity, BloomFilter bf) {
		this.dataBlockCapacity = dataBlockCapacity;
		this.bf = bf;
		this.count = count;
		this.timestamp = System.currentTimeMillis();
	}
	
	
	public ByteBuffer encode() {
		byte[] bs = KryoTools.serializ(bf);
		int c = HEAD_LEN + bs.length;
		ByteBuffer buf = ByteBuffer.allocateDirect(c);
		buf.putInt(count);
		buf.putLong(timestamp);
		buf.putInt(dataBlockCapacity);
		buf.putInt(bs.length);
		buf.put(bs);
		buf.flip();
		return buf;
	}
	
	
	/**
	 * 	布隆过滤器长度
	 */
	protected int bloomFilterByteLen = -1;
	protected byte[] bloomFilterBytes = null;
	public static MetaBlock decode(ByteBuffer buf, boolean readBloomFilterBytes) {
		MetaBlock mb = new MetaBlock(-1, -1, null);
		mb.count = buf.getInt();
		mb.timestamp = buf.getLong();
		mb.dataBlockCapacity = buf.getInt();
		mb.bloomFilterByteLen = buf.getInt();
		//	读到内存里，堆外释放掉
		if (readBloomFilterBytes) {
			mb.bloomFilterBytes = new byte[mb.bloomFilterByteLen];
			buf.get(mb.bloomFilterBytes);
		}
		return mb;
	}
	public BloomFilter getBloomFilter() {
		if (bf == null) {
			if (bloomFilterBytes != null) {
				bf = KryoTools.deSerialize(bloomFilterBytes, BloomFilter.class);
			}
		}
		return bf;
	}


	public int getCount() {
		return count;
	}
	public void setCount(int count) {
		this.count = count;
	}
	public int getDataBlockCapacity() {
		return dataBlockCapacity;
	}
	public void setDataBlockCapacity(int dataBlockCapacity) {
		this.dataBlockCapacity = dataBlockCapacity;
	}
	public BloomFilter getBf() {
		return bf;
	}
	public void setBf(BloomFilter bf) {
		this.bf = bf;
	}
	public long getTimestamp() {
		return timestamp;
	}
	public void setTimestamp(long timestamp) {
		this.timestamp = timestamp;
	}
	
	
}
